#!/usr/bin/env bash
# SPDX-License-Identifier: BSD-3-Clause

set -e

git config --global --add safe.directory "$DOCKER_BUILD_DIR"

source $DOCKER_BUILD_DIR/.ci/docker-prelude.sh

if [ -d build ]; then
  rm -rf build
fi

# Do not run tests when building on coverity_scan branch
if [ "${COVERITY_SCAN_BRANCH}" == 1 ]; then
  echo "Coverity scan branch detected, not running build nor tests...exiting!"
  exit 0
fi

# If it's clang, enable asan
if [[ "$CC" == clang* ]]; then
  echo "Detecting clang, enable asan"
  export CFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer"
  echo "Exported CFLAGS=$CFLAGS"
  config_flags="--disable-hardening"
  echo "Disabled configure option hardening"
  export ASAN_ENABLED=true
  echo "Exported ASAN_ENABLED=$ASAN_ENABLED"
  # To get line numbers set up the asan symbolizer
  clang_version=`$CC --version | head -n 1 | cut -d\  -f 3-3 | cut -d\. -f 1-2`
  # Sometimes the version string has an Ubuntu on the front of it and the field
  # location changes
  if [ $clang_version == "version" ]; then
    clang_version=`$CC --version | head -n 1 | cut -d\  -f 4-4 | cut -d\. -f 1-2`
  fi
  echo "Detected clang version: $clang_version"
  ASAN_SYMBOLIZER_PATH="/usr/lib/llvm-$clang_version/bin/llvm-symbolizer"
  if [ -e "$ASAN_SYMBOLIZER_PATH" ]; then
    export ASAN_SYMBOLIZER_PATH
    echo "Exported ASAN_SYMBOLIZER_PATH=$ASAN_SYMBOLIZER_PATH"
  else
    echo "No llvm symbolizer found at: $ASAN_SYMBOLIZER_PATH"
    unset ASAN_SYMBOLIZER_PATH
  fi
else #GCC
  export CFLAGS="-Wall -Wextra -Werror"
  echo "Exported CFLAGS=$CFLAGS"
  config_flags="--disable-hardening --enable-code-coverage"
fi

# Bootstrap in the tpm2.0-tss tools directory
./bootstrap

# Multiarch builds
if [[ ${MULTIARCH_BUILD} == "true" ]]; then
  mkdir ./build
  cd ./build
  ../configure --enable-unit --disable-fapi $config_flags
  make check
  exit 0
fi

# clang has asan enabled with options exported that fail
# make distcheck, so only do this with gcc.
# Do a make distcheck in the root, clear it and than
# cd to the variant directory.
if [[ "$CC" != clang* ]]; then
    ./configure
    make distcheck
    make distclean
fi

# Make a build variant directory and change to it
mkdir ./build
pushd ./build

# Run scan-build for gcc only.
# Scan-build does not work with clang because of asan linking errors.
if [[ "$CC" != clang* ]]; then
    scan-build ../configure --enable-unit $config_flags
    scan-build --status-bugs make -j$(nproc)

    # scan-build causes test_tpm2_session to fail, so
    # rebuild after running scan-build.
fi

../configure --enable-unit $config_flags
make -j$(nproc)
make -j check

popd

#
# Backwards compatibility test for ensuring we do not break the tool options
# determined in 4.X release.
#
if [[ "${TPM2_TSS_VERSION}" == "master" && "$CC" != clang* ]];then
  echo "tpm2-tools v4.X compatibility test follows"
  git fetch origin refs/tags/4.3.0:refs/tags/4.3.0
  git checkout 4.3.0 test/integration/tests
  git clean -fdx tests/integration/fapi
  #
  # RSA OAEP decryption was enabled as a feature after 4.X and so testing it
  # would signal a false compatibility test failure.
  #
  git checkout HEAD test/integration/tests/rsadecrypt.sh
  #
  # tpm2_getekcertificate is known to break backwards compatibility
  #
  git checkout HEAD test/integration/tests/getekcertificate.sh
  #
  # tpm2_getcap had vendor option added, so older test fail by looping
  # through the list output and tring them, but the simulator does not
  # support reading a vendor command.
  git checkout HEAD test/integration/tests/getcap.sh
  #
  # symlink is an irrelevant test for 4.X branch
  #
  rm test/integration/tests/symlink.sh

  #
  # Beyond 4.X release, the tpm2-tools were combined into a single
  # busybox style binary "tpm2". The following makes adjustments
  # to the tool-name which essentially invokes the same tools.
  #
  for f in `find test/integration/tests -iname '*.sh'`
  do
      for i in `find tools -iname 'tpm2*.c'`
      do
          test=$(basename $i .c)
          replace=$(basename $i .c | sed  's/tpm2_//g')
          sed -i "s/$test/tpm2 $replace/g" $f
      done
  done

  ./bootstrap

  mkdir compatibility_testbuild
  pushd compatibility_testbuild
  ../configure --enable-unit --disable-fapi --disable-hardening --with-tpmsim=tpm_server
  make -j$(nproc)
  make check -j$(nproc)
  popd
  git reset --hard HEAD
fi

# back in root git directory, check for whitespace errors. We do this post CI
# so people can verify the rest of their patch works in CI before dying.
# git diff --check fails with a non-zero return code causing the shell to die
# as it has a set -e executed.
check_branch="origin/${TRAVIS_BRANCH:-master}"
[ -z "$TRAVIS_TAG" ] && git fetch "$check_branch" && git diff --check "$check_branch"

if [ "$ENABLE_COVERAGE" == "true" ]; then
    bash <(curl -s https://codecov.io/bash)
else
    echo "ENABLE_COVERAGE not true, got \"$ENABLE_COVERAGE\""
fi

exit 0
